#include <gtk/gtk.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h> // 添加头文件
typedef struct
{
    GtkWidget *entry_path;
    GtkWidget *entry_keyword;
    GtkTextBuffer *text_buffer;
} SearchWidgets;

typedef struct
{
    GtkTextBuffer *buffer;
    char *line;
} TextUpdate;

// UI线程中插入文本
gboolean append_text(gpointer data)
{
    TextUpdate *update = (TextUpdate *)data;
    GtkTextIter end;
    gtk_text_buffer_get_end_iter(update->buffer, &end);
    gtk_text_buffer_insert(update->buffer, &end, update->line, -1);
    gtk_text_buffer_insert(update->buffer, &end, "\n", -1);
    g_free(update->line);
    g_free(update);
    return FALSE;
}

// 递归搜索文件名中包含 keyword 的文件
void search_files(const char *path, const char *keyword, GtkTextBuffer *buffer)
{
    DIR *dir = opendir(path);
    if (!dir)
        return;

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL)
    {
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;

        char full_path[1024];
#ifdef _WIN32
        snprintf(full_path, sizeof(full_path), "%s\\%s", path, entry->d_name);
#else
        snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
#endif

        struct stat st;
        if (stat(full_path, &st) == 0 && S_ISDIR(st.st_mode))
        {
            search_files(full_path, keyword, buffer);
        }
        else if (strstr(entry->d_name, keyword))
        {
            TextUpdate *update = g_new(TextUpdate, 1);
            update->buffer = buffer;
            update->line = g_strdup(full_path);
            g_idle_add(append_text, update);
        }
    }
    closedir(dir);
}

// 工作线程入口
gpointer threaded_search(gpointer user_data)
{
    SearchWidgets *widgets = (SearchWidgets *)user_data;
    const char *path = gtk_editable_get_text(GTK_EDITABLE(widgets->entry_path));
    const char *keyword = gtk_editable_get_text(GTK_EDITABLE(widgets->entry_keyword));
    gtk_text_buffer_set_text(widgets->text_buffer, "", -1); // 清空结果
    search_files(path, keyword, widgets->text_buffer);
    return NULL;
}

// 按钮回调
void on_search_clicked(GtkButton *button, gpointer user_data)
{
    g_thread_new("search_thread", threaded_search, user_data);
}

int main(int argc, char *argv[])
{
    gtk_init();

    GtkWidget *window = gtk_window_new();
    gtk_window_set_title(GTK_WINDOW(window), "文件搜索工具");
    gtk_window_set_default_size(GTK_WINDOW(window), 600, 400);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_window_destroy), NULL);

    GtkWidget *grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
    gtk_widget_set_margin_top(grid, 10);
    gtk_widget_set_margin_start(grid, 10);
    gtk_widget_set_margin_end(grid, 10);
    gtk_widget_set_margin_bottom(grid, 10);

    GtkWidget *label1 = gtk_label_new("起始路径：");
    GtkWidget *entry_path = gtk_entry_new();
#ifdef _WIN32
    gtk_editable_set_text(GTK_EDITABLE(entry_path), "C:\\");
#else
    gtk_editable_set_text(GTK_EDITABLE(entry_path), "/");
#endif

    GtkWidget *label2 = gtk_label_new("关键词：");
    GtkWidget *entry_keyword = gtk_entry_new();

    GtkWidget *button = gtk_button_new_with_label("搜索");

    GtkWidget *scrolled = gtk_scrolled_window_new();
    gtk_widget_set_vexpand(scrolled, TRUE);
    gtk_widget_set_hexpand(scrolled, TRUE);

    GtkWidget *textview = gtk_text_view_new();
    gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE);
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview), FALSE);
    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolled), textview);

    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));

    SearchWidgets *widgets = g_malloc(sizeof(SearchWidgets));
    widgets->entry_path = entry_path;
    widgets->entry_keyword = entry_keyword;
    widgets->text_buffer = buffer;

    g_signal_connect(button, "clicked", G_CALLBACK(on_search_clicked), widgets);

    // 放置组件
    gtk_grid_attach(GTK_GRID(grid), label1, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), entry_path, 1, 0, 2, 1);
    gtk_grid_attach(GTK_GRID(grid), label2, 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), entry_keyword, 1, 1, 2, 1);
    gtk_grid_attach(GTK_GRID(grid), button, 0, 2, 3, 1);
    gtk_grid_attach(GTK_GRID(grid), scrolled, 0, 3, 3, 1);

    gtk_window_set_child(GTK_WINDOW(window), grid);
    gtk_widget_show(window);

    gtk_main();
    return 0;
}
